# -*- coding: utf-8 -*-

from email import header, parser, utils

import base64
import datetime

encoding = 'utf-8'


def smtp(host='', port=25, username='', password=''):
    import smtplib

    server = smtplib.SMTP(host=host, port=port)
    server.set_debuglevel(1)
    server.login(user=username, password=password)

    server.quit()

    pass


def pop3(host='', port=110, username='', password=''):
    import poplib

    pop3_server = poplib.POP3(host=host, port=port)
    pop3_server.set_debuglevel(1)
    pop3_server.user(user=username)
    pop3_server.pass_(password)

    message_count, mailbox_size = pop3_server.stat()
    print('邮件总数:%d\n邮箱容量:%d' % (message_count, mailbox_size))
    resp_code, mail_list, resp_size = pop3_server.list()

    # 倒叙读取邮件内容
    # for email_index in range(1, len(mail_list)):
    #     read_mail(pop3_server, email_index)
    #     pass
    read_mail(pop3_server, 18)

    pop3_server.quit()
    pass


def read_mail(server, index):
    # 通过邮件编号读取邮件，注意邮件编号是从1开始的
    # 读取最新一份邮件就是以邮件总数为编号
    resp_code, mail_info, resp_size = server.retr(index)

    # 解析邮件文本内容
    mail_text = b'\r\n'.join(mail_info).decode(encoding=encoding)
    mail_data = parser.Parser().parsestr(text=mail_text)

    # 获取主题
    subject, charset = header.decode_header(header=mail_data['Subject'])[0]
    subject = subject.decode(encoding=charset)
    print('subject:%s' % subject)

    # 发送时间，格式：%a, %d %b %Y %H:%M:%S %z (%Z)
    # 'Sat, 5 Mar 2022 23:30:13 +0800 (CST)'
    send_date = mail_data['Date']
    send_date = send_date[0:send_date.rfind('(') - 1]
    dtf = '%a, %d %b %Y %H:%M:%S %z'
    send_date = datetime.datetime.strptime(send_date, dtf)
    print('发送时间:%s' % send_date.strftime('%Y-%m-%d %H:%M:%S'))

    # 发件人
    from_name, from_addr = utils.parseaddr(addr=mail_data['From'])
    if len(from_name) != 0:
        from_name, charset = header.decode_header(header=from_name)[0]
        from_name = from_name.decode(charset)
        pass
    print('发件人邮箱:%s\n发件人别名:%s' % (from_addr, from_name))

    # 收件人
    to_name, to_addr = utils.parseaddr(addr=mail_data['To'])
    if len(to_name) != 0:  # 处理别名为空的情况
        to_name, charset = header.decode_header(header=to_name)[0]
        to_name = to_name.decode(charset)
        pass
    print('收件人邮箱:%s\n发件人别名:%s' % (to_addr, to_name))

    # 解析邮件
    parse_email(mail_data)

    pass


def parse_email(mail_data):
    """递归方式解析multipart"""
    for multipart in mail_data.walk():
        if multipart.is_multipart():
            payload = multipart.get_payload()
            for message in payload:
                parse_email(message)

                pass
            pass
        else:
            content_type = multipart.get_content_type()
            if content_type == 'text/plain' or content_type == 'text/html':
                content = multipart.get_payload(decode=True).decode(encoding)
                if content_type == 'text/html':
                    pass
                print('content:%s' % content)
                pass
            elif content_type == 'application/octet-stream':  # 附件
                filename = multipart.get_filename()
                file_name, charset = header.decode_header(header=filename)[0]
                if len(filename) != 0:
                    file_name = file_name.decode(charset)
                    print('文件名称:%s' % file_name)
                    payload = multipart.get_payload(decode=True)
                    with open('/Users/hn/Desktop/' + file_name, 'wb') as file:
                        file.write(payload)
                        pass
                    pass
                pass
            pass
        pass


if __name__ == '__main__':
    smtp_host = 'smtp.qq.com'
    # smtp_host = 'smtp.163.com'
    # smtp_port = 25
    smtp_port = 465  # SSL

    # pop3_host = 'pop.qq.com'
    pop3_host = 'pop.exmail.qq.com'
    # pop3_host = 'pop.163.com'
    pop3_port = 110
    # pop3_port = 995  # SSL

    # imap_host = 'imap.exmail.qq.com'
    imap_port = 993  # SSL

    user = input('email:')
    passwd = input('password:')

    smtp(host=smtp_host, port=smtp_port, username=user, password=passwd)
    pop3(host=pop3_host, port=pop3_port, username=user, password=passwd)

    pass
